<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>3_react生命周期(新)</title>
</head>
<body>
<!-- 准备好一个"容器" -->
<div id="test1"></div>

<!-- 引入React核心库 -->
<script type="text/javascript" src="../js/17.0.1/react.development.js"></script>
<!-- 引入react-dom，用于支持react操作DOM -->
<script type="text/javascript" src="../js/17.0.1/react-dom.development.js"></script>
<!-- 引入babel，用于将jsx转为js -->
<script type="text/javascript" src="../js/17.0.1/babel.min.js"></script>
<!-- 引入prop-types，用于对组件标签属性进行限制 -->
<script type="text/javascript" src="../js/17.0.1/prop-types.js"></script>

<script type="text/babel">
  /**
    一、初始化阶段：由ReactDom.render()触发--初次渲染
        1、constructor()
        2、getDerivedStateFromProps
        3、render()
        4、componentDidMount() =====> 常用
           一般在这个钩子中做一些初始化的事，例如：开启定时器、发送网络请求、订阅消息

    二、更新阶段：由组件内部this.setState()或父组件render触发
        1、getDerivedStateFromProps
        2、shouldComponentUpdate()
        3、render() =====> 必须使用的一个
        4、getSnapshotBeforeUpdate
        5、componentDidUpdate()

    三、卸载组件：由ReactDOM.unmountComponentAtNode()触发
        1、componentWillUnmount() =====> 常用
           一般在这个钩子中做一些收尾的事，例如：关闭定时器、取消订阅消息
  */
  // 1.创建组件
  class Count extends React.Component {

    // 构造器
    constructor(props) {
      console.log('Count---constructor')
      super(props);
      // 初始化状态
      this.state = {count: 0}
    }

    // 加1按钮的回调
    add = () => {
      // 获取原状态
      const {count} = this.state
      // 更新状态
      this.setState({count: count + 1})
    }

    // 卸载组件按钮的回调
    death = () => {
      ReactDOM.unmountComponentAtNode(document.getElementById('test1'))
    }

    // 强制更新按钮的回调
    force = () => {
      this.forceUpdate()
    }

    // 若state的值在任何时候都取决于props，那么可以使用getDerivedStateFromProps
    static getDerivedStateFromProps(props, state) {
      console.log('getDerivedStateFromProps', props, state)
      return null
    }

    // 在更新之前获取快照
    getSnapshotBeforeUpdate() {
      console.log('getSnapshotBeforeUpdate')
      return 'atguigu'
    }

    // 组件挂载完毕的钩子
    componentDidMount() {
      console.log('Count---componentDidMount')
    }

    // 控制组件更新的"阀门"
    shouldComponentUpdate() {
      console.log('Count---shouldComponentUpdate')
      return true
    }

    // 组件更新完毕的钩子
    componentDidUpdate(prevProps, prevState, snapshotValue) {
      console.log('Count---componentDidUpdate', prevProps, prevState, snapshotValue)
    }

    render() {
      console.log('Count---render')
      const {count} = this.state
      return (
        <div>
          <h2>当前求和为：{count}</h2>
          <button onClick={this.add}>点我+1</button>
          <button onClick={this.death}>卸载组件</button>
          <button onClick={this.force}>不更改任何状态中的数据，强制更新一下</button>
        </div>
      )
    }
  }

  // 2.渲染组件到页面
  ReactDOM.render(<Count count={199}/>, document.getElementById('test1'))
</script>
</body>
</html>
